package com.neusoft.chess.view;

import com.neusoft.chess.BingChess;
import com.neusoft.chess.BossChess;
import com.neusoft.chess.Chess;
import com.neusoft.chess.PaoChess;
import com.neusoft.chess.factory.ChessFactory;
import com.neusoft.chess.myenum.ChessType;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * @Author: duan
 * @Date: Create in 10:14 2020/9/28
 */
public class GamePanel extends JPanel {
    private Chess selectedChess;//保存被选中的棋子
    private Map<Point, Chess> map;
    private int curPlayer = Chess.player_red;//当前走棋的选手阵营

    public GamePanel() {
        createChesses();
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                int x = e.getX();
                int y = e.getY();
                Point p = Chess.getPointFromXY(x, y);
                /*
                    选中棋子
                        原来没有选中过棋子
                    重新选择
                        原来选中过棋子，第二次点击的地方有棋子且同一个阵营，即为重新选择
                    移动
                        选中了棋子，第二点击的地方没有棋子，且符合移动规则
                    吃子
                        选中了棋子，第二点击的地方有敌方阵营的棋子，且符合移动规则
                 */
                if (selectedChess == null) {
                    selectedChess = map.get(p);
                    //如果当前选手，选择了敌方棋子，无效
                    if (selectedChess != null && selectedChess.getPlayer() != curPlayer) {
                        selectedChess = null;
                    }
                    System.out.println("当前选中的棋子为：" + selectedChess);
                } else {
                    /*
                        重新选择
                        移动
                        吃子
                     */
                    Chess c = map.get(p);//获取第二次点击的位置上的棋子
                    if (c == null) {
                        //移动
                        System.out.println("移动");
                        if (selectedChess.isAbleMove(p, map)) {
                            //删除旧的key
                            map.remove(selectedChess.getP());
                            //修改了棋子对象的坐标
                            selectedChess.setP(p);
                            //更新map集合
                            map.put(selectedChess.getP(), selectedChess);
                            over();
                        }
                    } else {
                        if (c.getPlayer() == selectedChess.getPlayer()) {
                            //重新选择
                            System.out.println("重新选择");
                            selectedChess = c;
                        } else {
                            //吃子
                            System.out.println("吃子");
                            if (selectedChess.isAbleMove(p, map)) {
                                //删除被吃掉的棋子
                                map.remove(p);
                                //删除旧的key
                                map.remove(selectedChess.getP());
                                //修改了棋子对象的坐标
                                selectedChess.setP(p);
                                //更新map集合
                                map.put(selectedChess.getP(), selectedChess);
                                over();
                            }
                        }
                    }
                }
                repaint();//刷新棋盘
            }
        });
    }

    /**
     * 走完一步，换另一个走棋
     */
    private void over() {
        curPlayer = curPlayer == Chess.player_red ? Chess.player_black : Chess.player_red;
        selectedChess = null;
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        drawQipan(g);
        drawChesses(g);
        if (selectedChess != null) {
            selectedChess.drawSelectedRect(g);
        }
    }

    /**
     * 绘制棋盘背景
     * @param g
     */
    private void drawQipan(Graphics g) {
        Image bg = Toolkit.getDefaultToolkit().getImage("pic/qipan.jpg");
        g.drawImage(bg, 0, 0, this);
    }

    /**
     * 创建所有棋子，但不绘制
     */
    private void createChesses() {
        map = new HashMap<>();//初始化map集合
//        ChessType[] types = {ChessType.CHE, ChessType.CHE, ChessType.MA, ChessType.MA, ChessType.XIANG, ChessType.XIANG, ChessType.SHI, ChessType.SHI, ChessType.BOSS, ChessType.PAO, ChessType.PAO, ChessType.BING, ChessType.BING, ChessType.BING, ChessType.BING, ChessType.BING};
        String packageName = "com.neusoft.chess.";
        String[] types = {"CheChess", "CheChess", "MaChess", "MaChess", "XiangChess", "XiangChess", "ShiChess", "ShiChess", "BossChess", "PaoChess", "PaoChess", "BingChess", "BingChess", "BingChess", "BingChess", "BingChess"};
        int[] pxs = {1, 9, 2, 8, 3, 7, 4, 6, 5, 2, 8, 1, 3, 5, 7, 9};
        Chess c = null;
        for (int i = 0; i < types.length; i++) {
//            c = ChessFactory.createChess(types[i], pxs[i], Chess.player_red);
            c = ChessFactory.createChess(packageName, types[i], pxs[i], Chess.player_red);
            map.put(c.getP(), c);
        }

        for (int i = 0; i < types.length; i++) {
//            c = ChessFactory.createChess(types[i], pxs[i], Chess.player_black);
            c = ChessFactory.createChess(packageName, types[i], pxs[i], Chess.player_black);
            c.reserve();
            map.put(c.getP(), c);
        }
//        Chess c = ChessFactory.createChess(ChessFactory.ChessType.CHE, 1, Chess.player_red);
//        c = ChessFactory.createChess(ChessFactory.ChessType.MA, 1, Chess.player_red);
        /*
            BingChess c = new BingChess(1, 0);
            耦合度最高，需要解耦
            解耦即将代码的复用提高
         */
//        Chess c = new BingChess(1, 0);
//        map.put(c.getP(), c);
//        c = new BingChess(3, 0);
//        map.put(c.getP(), c);
//        c = new PaoChess(2, 0);
//        map.put(c.getP(), c);
//        c = new PaoChess(8, 0);
//        map.put(c.getP(), c);
//        c = new BossChess(5, 0);
//        map.put(c.getP(), c);
//        c = new BingChess(3, 1);
//        c.reserve();
//        map.put(c.getP(), c);
    }

    /**
     * 绘制所有棋子
     * @param g
     */
    private void drawChesses(Graphics g) {
        Set<Point> set = map.keySet();
        Iterator<Point> it = set.iterator();
        Point key = null;
        Chess value = null;
        while (it.hasNext()) {
            key = it.next();
            value = map.get(key);
            value.draw(g, this);
        }
    }
}
